"""
自定义分页组件,使用方法
在视图函数中：
def prety_list(request):
# 1.根据自己情况筛选自己的所有数据
    data_set = models.PretyNum.objects.all()
# 2.实例化分页类对象
    page_object = Pagination(request, query_set=data_set) # 实例化一个分页类
    page_str = page_object.html() #返回翻页html标签
    context = { # 用字典放给模板的各个数据
                'data_set': page_object.data_queryset, # 分完页的数据
               'page_str': page_str, # 页码
               }
    print(serach_dict)
    return render(request, 'prety_list.html', context)

在HTML页面中：
{% for obj in data_set %}
    {{ obj.XX }}    用循环展示分页数据
{% endfor %}
<ul class="pagination">
    {{ page_str }}    显示视图函数中的翻页html标签
</ul>
"""
import copy
from django.utils.safestring import mark_safe


class Pagination(object):
    def __init__(self, request, query_set, page_param="page", page_size=10, size=3):
        """
        :param request:请求的对象
        :param query_set:用来分页的原数据（按自己要求来）
        :param page_param:在URL中获取分页的参数，例如/prety/list/?page=6
        :param page_size:每页展示多少条数据
        :param size:分页标签显示为当前页的前多少页后多少页
        """
        get_object = copy.deepcopy(request.GET)  # 处理搜索功能和翻页功能的参数拼接,因无法直接更改request的参数所以进行深拷贝后再更改参数为True
        get_object._mutable = True
        self.get_object = get_object

        # 对接收到的page进行类型处理
        page = request.GET.get(page_param, '1')
        if page.isdecimal():
            page = int(page)
        else:
            page = 1
        self.page = page
        self.page_size = page_size
        # 每页数据起始和结束
        self.start = (page - 1) * page_size
        self.end = page * page_size

        # 翻页标签
        self.count = query_set.count()  # 总条数
        self.page_count, self.y = divmod(self.count, self.page_size)  # 求数据库总页数
        if self.y > 0:
            self.page_count += 1
        self.data_queryset = query_set[self.start:self.end] # 得到分页后的单页数据
        self.size = size
        self.page_param = page_param

    def html(self):
        # 当前页码小于size 控制标签边界值
        self.start_page = self.page - self.size
        self.end_page = self.page + self.size
        # 数据库数据库很少情况：
        if self.page_count < 2 * self.size + 1:
            self.start_page = 1
            self.end_page = self.page_count
        else:  # 数据库数据比较多
            # 当前页小于等于size
            if self.page <= self.size:
                self.start_page = 1
                self.end_page = self.size * 2 + 1
                # 当前页码加size大于总页数
            elif (self.page + self.size) > self.page_count:
                self.start_page = self.page_count - 2 * self.size
                self.end_page = self.page_count

        self.page_list = []  # 定义一个列表存所有页码字符串
        # 上一页
        if self.page > 1:
            self.get_object.setlist(self.page_param, [self.page - 1]) #将url原本的参数和页码拼接起来
            prev = '<li ><a href="?{}">上一页</a></li>'.format(self.get_object.urlencode())
        else:
            self.get_object.setlist(self.page_param, [1])
            prev = '<li ><a href="?{}">上一页</a></li>'.format(self.get_object.urlencode())
        self.page_list.append(prev)
        # 页码
        for i in range(self.start_page, self.end_page + 1):
            if i == self.page:
                self.get_object.setlist(self.page_param, [i])
                ela = '<li class="active"><a href="?{}">{}</a></li>'.format(self.get_object.urlencode(), i)
            else:
                self.get_object.setlist(self.page_param, [i])
                ela = '<li><a href="?{}">{}</a></li>'.format(self.get_object.urlencode(), i)
            self.page_list.append(ela)
        # 下一页
        if self.page < self.page_count:
            self.get_object.setlist(self.page_param, [self.page + 1])
            prev = '<li ><a href="?{}">下一页</a></li>'.format(self.get_object.urlencode())
        else:
            self.get_object.setlist(self.page_param, [self.page_count])
            prev = '<li ><a href="?{}">下一页</a></li>'.format(self.get_object.urlencode())
        self.page_list.append(prev)
        # 跳转页
        go_to_str = """                    <form method="get" style="float: left">
                               <div class="input-group" style="width:100px;">
                                   <input type="text" value="{}" name="page" class="form-control" placeholder="页码">
                                   <span class="input-group-btn">
                       <button class="btn btn-default" type="submit">》</button>
                     </span>
                               </div>
                               </form>""".format(self.page)
        self.page_list.append(go_to_str)
        # 将列表存的所有页码字符串放入字符串并返回给模板页
        self.page_str = mark_safe(''.join(self.page_list))
        return self.page_str
